package com.ifly.voice.view;

import android.R.integer;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.widget.ImageView;

public class DynamicButton extends ImageView
{

	private static final int centreArea = 1;
	private static final int rightArea = 2;
	private static final int lefttArea = 3;
	private static final int topArea = 4;
	private static final int downArea = 5;
	private static final float minScale = 0.985f;
	private static final float resetSacle = (float) 1.0f / minScale;
	private static final int degreeRotate = 10;
	private static final int scaleCount = 6;
	PaintFlagsDrawFilter filter;
	private int vWidth;
	private int vHeight;
	private float coordx;
	private float coordY;
	private float scale0;
	private RectF centre;
	private Point cenPoint;

	public DynamicButton(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		init();
	}

	private void init()
	{
		filter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);;
		camera = new Camera();

		Drawable drawable = getDrawable();
		BitmapDrawable bd = (BitmapDrawable) drawable;
		bd.setAntiAlias(true);
		// boolean antiAlias = bd.getPaint().isAntiAlias();
		// LogUtils.d("antiAlias="+antiAlias);
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh)
	{
		super.onSizeChanged(w, h, oldw, oldh);
		vWidth = w - getPaddingLeft() - getPaddingRight();
		vHeight = h - getPaddingTop() - getPaddingBottom();
		scale0 = (float) vHeight / vWidth;

		cenPoint = new Point(vWidth / 2, vHeight / 2);
		centre = new RectF(vWidth / 3, vHeight / 3, vWidth * 2 / 3, vHeight * 2 / 3);
	}

	int state = 0;
	private Matrix matrix = new Matrix();

	private Camera camera;

	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		int action = event.getAction();
		if (action == MotionEvent.ACTION_DOWN)
		{
			coordx = event.getX();
			coordY = vHeight - event.getY();
			if (centre.contains(coordx, event.getY()))
			{
				state = centreArea;
			}
			else
			{
				float rx = Math.abs(coordx - vWidth / 2);
				float ry = Math.abs(coordY - vHeight / 2);
				float scale1 = ry / rx;
				if (scale1 < scale0)
				{
					if (coordx > cenPoint.x)
					{
						state = rightArea;
					}
					else
					{
						state = lefttArea;
					}
				}
				else
				{
					if (coordY > cenPoint.y)
					{
						state = topArea;
					}
					else
					{
						state = downArea;
					}
				}
			}
			onStateChanged(state);
		}
		else if (action == MotionEvent.ACTION_MOVE)
		{
		}
		else if (action == MotionEvent.ACTION_UP)
		{
			onStateReset(state);
		}
		return true;
	}

	Runnable scaleOn = new Runnable()
	{
		int count;
		@Override
		public void run()
		{
			if (count < scaleCount)
			{
				beginScale(minScale);
				count++;
				post(this);
			}
			else
			{
				count = 0;
			}

		}
	};

	Runnable scaleOff = new Runnable()
	{
		int count = 0;
		@Override
		public void run()
		{
			if (count < scaleCount)
			{
				beginScale(resetSacle);
				count++;
				post(this);
			}
			else
			{
				count = 0;
			}
		}
	};

	Runnable rotateOn = new Runnable()
	{
		int i = 0;
		@Override
		public void run()
		{
			if (i < degreeRotate)
			{
				if (state == rightArea)
				{
					beginRolateRight(i);
				}
				else if (state == lefttArea)
				{
					beginRolateLeft(i);
				}
				else if (state == topArea)
				{
					beginRolateTop(i);
				}
				else if (state == downArea)
				{
					beginRolateDown(i);
				}
				i++;
				post(this);
			}
			else
			{
				i = 0;
			}
		}
	};

	Runnable rotateOff = new Runnable()
	{
		int i = degreeRotate - 1;
		@Override
		public void run()
		{
			if (i >= 0)
			{
				if (state == rightArea)
				{
					beginRolateRight(i);
				}
				else if (state == lefttArea)
				{
					beginRolateLeft(i);
				}
				else if (state == topArea)
				{
					beginRolateTop(i);
				}
				else if (state == downArea)
				{
					beginRolateDown(i);
				}
				i--;
				post(this);
			}
			else
			{
				i = degreeRotate - 1;
			}
		}
	};

	private void onStateChanged(int state)
	{
		if (state == centreArea)
		{
			post(scaleOn);
		}
		else
		{
			post(rotateOn);
		}

	}
	private void onStateReset(int state)
	{
		if (state == centreArea)
		{
			post(scaleOff);
		}
		else
		{
			post(rotateOff);
		}
	}
	private synchronized void beginRolateDown(int i)
	{
		matrix.set(getImageMatrix());
		camera.save();
		camera.rotateX(-i);
		camera.getMatrix(matrix);
		camera.restore();
		matrix.preTranslate(-cenPoint.x, -0);
		matrix.postTranslate(cenPoint.x, 0);
		setImageMatrix(matrix);
	}

	private synchronized void beginRolateTop(int i)
	{
		matrix.set(getImageMatrix());
		camera.save();
		camera.rotateX(i);
		camera.getMatrix(matrix);
		camera.restore();
		matrix.preTranslate(-cenPoint.x, -vHeight);
		matrix.postTranslate(cenPoint.x, vHeight);
		setImageMatrix(matrix);
	}

	private synchronized void beginRolateLeft(int i)
	{
		matrix.set(getImageMatrix());
		camera.save();
		camera.rotateY(-i);
		camera.getMatrix(matrix);
		camera.restore();
		matrix.preTranslate(-vWidth, -cenPoint.y);
		matrix.postTranslate(vWidth, cenPoint.y);
		setImageMatrix(matrix);
	}

	private synchronized void beginRolateRight(int i)
	{
		matrix.set(getImageMatrix());
		camera.save();
		camera.rotateY(i);
		camera.getMatrix(matrix);
		camera.restore();
		matrix.preTranslate(0, -cenPoint.y);
		matrix.postTranslate(0, cenPoint.y);
		setImageMatrix(matrix);
	}

	private synchronized void beginScale(float scale)
	{
		matrix.set(getImageMatrix());
		int scaleX = (int) (vWidth * 0.5f);
		int scaleY = (int) (vHeight * 0.5f);
		matrix.postScale(scale, scale, scaleX, scaleY);
		setImageMatrix(matrix);
	}

	@Override
	protected void onDraw(Canvas canvas)
	{
		canvas.setDrawFilter(filter);
		super.onDraw(canvas);
	}
}
